Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Android app black screen issue when reopening after incomplete closing #3227

Merged
merged 2 commits into from
Aug 6, 2023
Merged

Conversation

Bigfoot71
Copy link
Contributor

The problem mentioned in issue #3127 has been fixed.

The black screen problem was therefore linked to several problems:

  1. The fact that the application remains in the background despite the end of android_main and activities. (it seems that this is a normal behavior of android to reload resources faster and that this is not managed from the same way depending on the system. I would have to try on a second device to see how it handles it).

  2. When we called CloseWindow() at the end of our program APP_CMD_TERM_WINDOW was also "called" (like when we quit the application without closing it) but given that the context was already destroyed, the second calls surface destruction, etc. led to a first EGL_BAD_DISPLAY error.

  3. Again in APP_CMD_TERM_WINDOW, after destroying the surface, we set contextRebindRequired to true, the application closes and we return to the Android home, but part of the memory is kept (like the stack). Then when reopening (if we haven't closed the application ourselves in the task manager, or that Android does not close it itself) the app still has contextRebindRequired set to true and therefore tries to rebind with a non-existent context, etc. And so we get black screen with a second time EGL_BAD_DISPLAY

However, there are two other minor issues that I have noticed.

  1. This behavior (part of the app that remains in memory) seems to vary depending on the device, overlay, Android version, etc. However, the static global variables that I have defined in my C program remain unchanged after closing and reopening (by closing, I mean the call to ANativeActivity_finish(app->activity) and the end of android_main). This can be problematic, although in normal cases, we define them within functions, but it's worth noting.

  2. The fact that we don't fully manage the app's lifecycle via AndroidCommandCallback poses certain minor problems. For example, if the user manually exits the application using the Android task manager while the app is running, we receive this error in the logs:

2023-08-06 18:11:32.713  1205-1325  InputDispatcher         system_server                        E  channel 'ad8bf9d com.raylib.raymob/com.raylib.raymob.NativeLoader (server)' ~ Channel is unrecoverably broken and will be disposed!

This error is often related to memory leaks according to StackOverflow responses. However, a proper operating system should be able to handle this upon program termination, I suppose, so I consider it minor, right? 🤔

Other than that, the app closes properly, APP_CMD_DESTROY is indeed "called" and the Java method onDestroy as well. So, if the application remains in the background, that is up to Android. No more error messages appear, and there are no apparent memory leaks in normal usage that could explain this.

Video example

I made a short video capture to show that everything was working correctly now (and without the use of exit(0)), and I also wanted to demonstrate the issue of the stack being kept in memory even after closing the application. However, since I was recording the video and it was taking up a lot of memory on my device, the system automatically unloaded the entire application, except at one point where you can see that counter was preserved despite the closure.

So, for the users of raylib on Android, remember to initialize your global variables inside functions each time the application starts to avoid problems related to this behavior.

This variable counter is a static global variable that is only initialized once to 0 during its declaration. The exit button simply breaks the main while loop, calls CloseWindow(), and the main ends.

XRecorder_06082023_195642.mp4

If ever things are not clear or poorly explained do not hesitate to ask me.

@raysan5 raysan5 merged commit c9864d8 into raysan5:master Aug 6, 2023
12 checks passed
@raysan5
Copy link
Owner

raysan5 commented Aug 6, 2023

@Bigfoot71 thank you very much for reviewing this issue! It's been a long time not using raylib on Android so I can't properly validate if this fix is the best one and it works for all users but I will merge it. We will see if any dev complains about it in the future...

@Bigfoot71
Copy link
Contributor Author

@raysan5 The code is what it should have been before I made a PR for the use of exit(0), which was used to avoid the black screen issue upon resuming the application.

A brief summary of the additions since then:

  • ANativeActivity_finish(app->activity) has been added at the end of android_main, along with a loop waiting for events in AndroidCommandCallback.
  • Additional safeguards during context detachment in the case of APP_CMD_TERM_WINDOW, still for AndroidCommandCallback.

This should not pose any issues. However, if similar problems persist, we can still temporarily reuse exit(0) until a solution is found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants